<!--
 * @Author: rxn 1003312535@qq.com
 * @Date: 2024-07-05 15:25:53
 * @LastEditors: rxn 1003312535@qq.com
 * @LastEditTime: 2024-07-09 16:37:11
 * @FilePath: \vue3-progect\src\views\example\three\geometry\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!--缓存几何-->
<template>
	<div :id="id"></div>
</template>

<script setup>
import * as THREE from "three";
import { AxesHelper } from "../../case/helper/AxesHelper";
import { CameraHelper } from "../../case/helper/CameraHelper";
import { WebGLRenderer } from "../../create/renderer";
import { OrbitControlsHelper } from "../../case/helper/OrbitControls";
import { PerspectiveCamera } from "../../create/camera";
import { onMounted } from "vue";

//场景
const scene = new THREE.Scene();
AxesHelper(THREE, scene);
const props = defineProps(["id"]);
onMounted(() => {
	let container = document.getElementById(props.id);

	const camera = PerspectiveCamera(
		THREE,
		90,
		container.offsetWidth / container.offsetHeight,
		0.1,
		1000
	);
	camera.position.z = 200;
	CameraHelper(THREE, scene, camera);
	const renderer = WebGLRenderer(THREE, container);
	OrbitControlsHelper(THREE, scene, camera, renderer);
	// PointMaterial();
	Geometry();
	function animate() {
		requestAnimationFrame(animate);
		renderer.render(scene, camera);
	}
	animate();
});

/**
 * 点、线、面、位置颜色
 */
const PointMaterial = () => {
	const vertices = new Float32Array([0, 0, 0, 50, 0, 0, 0, 100, 0, 0, 0, 100]);

	const geometry = new THREE.BufferGeometry();
	// // 创建属性缓冲区对象

	const attribute = new THREE.BufferAttribute(vertices, 3);
	geometry.setAttribute("position", attribute);

	//点
	const PointsMaterial = new THREE.PointsMaterial({
		color: 0xff0000
		// vertexColors: true
	});
	const point = new THREE.Points(geometry, PointsMaterial);
	scene.add(point);
	const normals = new Float32Array([
		0, 0, 1, 0, 0, 1,

		0, 1, 0, 0, 1, 0
	]);
	geometry.setAttribute("normal", new THREE.BufferAttribute(normals, 3));
	geometry.setAttribute("color", new THREE.BufferAttribute(normals, 3));
	console.log(geometry, "geometry.attributes.normal");

	//面
	const materialLambert = new THREE.MeshBasicMaterial({
		vertexColors: true,
		side: THREE.DoubleSide //两面可见
	});
	const mesh = new THREE.Mesh(geometry, materialLambert);
	scene.add(mesh);
	/**
	 * 顶点索引复
	 */
	const indexes = new Uint16Array([0, 1, 2, 0, 3, 1]);
	geometry.index = new THREE.BufferAttribute(indexes, 1);
};
const Geometry = () => {
	const geometry = new THREE.BoxGeometry(100, 100, 100);
	geometry.scale(1, 1, 1);
	geometry.rotateY(100);
	geometry.castShadow = true;
	//面
	const material = new THREE.MeshLambertMaterial({
		color: "#ff0000"
	});
	console.log(geometry, "geometry", geometry.faces);
	const mesh = new THREE.Mesh(geometry, material);
	mesh.castShadow = true;
	scene.add(mesh);
	//点
	const PointsMaterial = new THREE.PointsMaterial({
		color: "#ffff00",
		size: 10
	});
	const points = new THREE.Points(geometry, PointsMaterial);
	scene.add(points);
	//线
	const lineMaterial = new THREE.LineBasicMaterial({ color: "#ff00ff" });
	const line = new THREE.Line(geometry, lineMaterial);
	scene.add(line);

	//面
	const geometry1 = new THREE.PlaneGeometry(500, 500);
	const mesh1Material = new THREE.MeshLambertMaterial({ color: 0xaaaaaa });
	const planeMesh = new THREE.Mesh(geometry1, mesh1Material);
	// mesh1.scale.set(100, 1, 100);
	planeMesh.rotateX(-Math.PI / 2); //旋转网格模型
	planeMesh.position.y = -50; //设置网格模型y坐标
	// 设置接收阴影的投影面
	planeMesh.receiveShadow = true;
	scene.add(planeMesh);
	//环境光
	var ambient = new THREE.AmbientLight(0xaaaaaa);
	scene.add(ambient); //环境光对象添加到scene场景中
	//点光源
	var pointLight = new THREE.PointLight(0xffffff, 1000, 0, 0);
	//设置点光源位置，改变光源的位置
	pointLight.position.set(110, 55, 55);
	scene.add(pointLight);
	//点光源辅助
	const sphereSize = 1;
	const pointLightHelper = new THREE.PointLightHelper(pointLight, sphereSize);
	scene.add(pointLightHelper);
	// 设置用于计算阴影的光源对象
	// 方向光
	var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
	// 设置光源位置
	directionalLight.position.set(110, 55, 55);
	scene.add(directionalLight);
	// 设置用于计算阴影的光源对象
	directionalLight.castShadow = true;
	// 设置计算阴影的区域，最好刚好紧密包围在对象周围
	// 计算阴影的区域过大：模糊  过小：看不到或显示不完整
	directionalLight.shadow.camera.near = 0.5;
	directionalLight.shadow.camera.far = 300;
	directionalLight.shadow.camera.left = -50;
	directionalLight.shadow.camera.right = 50;
	directionalLight.shadow.camera.top = 200;
	directionalLight.shadow.camera.bottom = -100;
};
</script>

<style lang="less" scoped>
#three_container {
	height: 100%;
}
</style>
